<!-- @format -->

<template>
  <div class="markdown-content" v-html="renderedContent"></div>
</template>

<script lang="ts">
  import { defineComponent, computed } from 'vue'
  import MarkdownIt from 'markdown-it'
  import DOMPurify from 'dompurify'

  export default defineComponent({
    name: 'MarkdownRenderer',
    props: {
      content: {
        type: String,
        required: true,
        default: '',
      },
    },
    setup(props) {
      // 创建markdown-it实例
      const md = new MarkdownIt({
        html: true,
        linkify: true,
        typographer: true,
      })


      // 自定义标记器处理行内公式 $...$
      md.inline.ruler.before('escape', 'inline_math', (state, silent) => {
        const start = state.pos
        if (state.src[start] !== '$') return false

        // 查找结束的 $
        let end = start + 1
        while (end < state.src.length && state.src[end] !== '$') {
          end++
        }

        // 没有找到结束的 $ 或者内容为空
        if (end === state.src.length || end === start + 1) return false

        // 不处理转义的 $
        if (start > 0 && state.src[start - 1] === '\\') return false

        // 检查前后是否有字母或数字（避免误识别货币符号等）
        if (
          (start > 0 && /[\w]/.test(state.src[start - 1])) ||
          (end < state.src.length - 1 && /[\w]/.test(state.src[end + 1]))
        ) {
          return false
        }

        if (!silent) {
          const token = state.push('inline_math', '', 0)
          // 预处理公式内容，处理常见的问题
          let content = state.src.slice(start + 1, end)
          // 增强预处理 - 处理更多情况
          content = content
            // 修复常见的上下标问题
            .replace(/([_^])([a-zA-Z0-9]+)/g, '$1{$2}')
            // 处理分数
            .replace(/\\frac([^{])([^{])/g, '\\frac{$1}{$2}')
            .replace(/\\frac{([^}]+)}([^{])/g, '\\frac{$1}{$2}')
            // 处理特殊情况：二次方程根式
            .replace(/\\sqrt{b\^2-4ac}/g, '\\sqrt{b^{2}-4ac}')
            // 处理特殊符号
            .replace(/(\\pm|\\mp|\\times|\\div|\\cdot)([^\s{])/g, '$1 $2')
          token.content = content
          token.markup = '$'
        }

        state.pos = end + 1
        return true
      })

      // 自定义标记器处理块级公式 $$...$$
      md.block.ruler.before(
        'fence',
        'block_math',
        (state, startLine, endLine, silent) => {
          const start = state.bMarks[startLine] + state.tShift[startLine]
          const max = state.eMarks[startLine]

          // 检查开始标记 $$
          if (
            max - start < 2 ||
            state.src[start] !== '$' ||
            state.src[start + 1] !== '$'
          ) {
            return false
          }

          let line = startLine
          let found = false

          // 查找结束标记 $$
          while (line < endLine) {
            line++
            if (line >= endLine) break

            const start = state.bMarks[line] + state.tShift[line]
            const max = state.eMarks[line]
            if (start < max && state.src.slice(start, max).indexOf('$$') >= 0) {
              found = true
              break
            }
          }

          if (!found) return false

          // 不处理silent模式
          if (silent) return true

          let content = state
            .getLines(startLine, line, state.tShift[startLine], true)
            .replace(/^\$\$/, '')
            .replace(/\$\$$/, '')
            .trim()

          // 预处理块级公式内容，修复常见问题
          // 修复上下标问题 - 更全面的处理
          content = content
            // 基本的上下标处理
            .replace(/([_^])([a-zA-Z0-9]+)/g, '$1{$2}')
            // 确保sum和int等符号正确使用limits
            .replace(/(\\sum|\\int|\\prod)_(\S)/g, '$1_{$2}')
            .replace(/(\\sum|\\int|\\prod)\^(\S)/g, '$1^{$2}')
            // 处理平方根和根号
            .replace(/\\sqrt([^{])/g, '\\sqrt{$1}')
            // 处理特殊符号前后的空格
            .replace(/(\\pm|\\mp|\\times|\\div|\\cdot)([^\s{])/g, '$1 $2')
            // 确保分数正确格式化 - 更全面的处理
            .replace(/\\frac(\S)(\S)/g, '\\frac{$1}{$2}')
            .replace(/\\frac{([^}]+)}([^{])/g, '\\frac{$1}{$2}')
            .replace(/\\frac([^{])\{([^}]+)\}/g, '\\frac{$1}{$2}')
            // 处理复杂分数表达式
            .replace(/\\frac{([^{}]+)}{([^{}]+)}/g, (match, p1, p2) => {
              // 确保分子分母中的特殊字符和上下标被正确处理
              const processedP1 = p1
                .replace(/(\\pm|\\mp|\\times|\\div|\\cdot)/g, '{$1}')
                .replace(/([_^])([^{])/g, '$1{$2}')
              const processedP2 = p2
                .replace(/(\\pm|\\mp|\\times|\\div|\\cdot)/g, '{$1}')
                .replace(/([_^])([^{])/g, '$1{$2}')
              return `\\frac{${processedP1}}{${processedP2}}`
            })
            // 处理下标中的特殊情况
            .replace(/_\{([^}]*)\}/g, (match) => match.replace(/,/g, '{,}'))
            // 处理上标中的特殊情况
            .replace(/\^\{([^}]*)\}/g, (match) => match.replace(/,/g, '{,}'))
            // 处理特殊情况：二次方程根式
            .replace(/\\sqrt{b\^2-4ac}/g, '\\sqrt{b^{2}-4ac}')
            // 处理特殊情况：带有\pm的表达式
            .replace(/(\\pm|\\mp)\s*\\sqrt/g, '{$1}\\sqrt')

          const token = state.push('block_math', '', 0)
          token.content = content
          token.markup = '$$'
          token.map = [startLine, line + 1]

          state.line = line + 1
          return true
        },
      )

  
      // 计算渲染后的内容
      const renderedContent = computed(() => {
        if (!props.content) return ''

        // 渲染Markdown
        const rendered = md.render(props.content)

        // 使用DOMPurify清理HTML
        return DOMPurify.sanitize(rendered)
      })

      return {
        renderedContent,
      }
    },
  })
</script>

<style scoped>
  .markdown-content {
    font-family:
      -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
      Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    line-height: 1.6;
    color: #333;
    max-width: 100%;
    overflow-x: auto;
  }

  .markdown-content h1,
  .markdown-content h2,
  .markdown-content h3,
  .markdown-content h4,
  .markdown-content h5,
  .markdown-content h6 {
    margin-top: 1.5em;
    margin-bottom: 0.5em;
    font-weight: 600;
  }

  .markdown-content p {
    margin: 1em 0;
  }

  .markdown-content code {
    background-color: #f5f5f5;
    padding: 0.2em 0.4em;
    border-radius: 3px;
    font-family:
      'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
  }

  .markdown-content pre {
    background-color: #f5f5f5;
    padding: 1em;
    border-radius: 5px;
    overflow-x: auto;
  }

  .markdown-content blockquote {
    border-left: 4px solid #ddd;
    padding-left: 1em;
    color: #666;
    margin: 1em 0;
  }

  .markdown-content .math-block {
    overflow-x: auto;
    margin: 1em 0;
    text-align: center;
  }

  .markdown-content .math-error {
    color: #e53935;
    background-color: #ffebee;
    padding: 0.2em 0.4em;
    border-radius: 3px;
  }

 
</style>
